<?php


namespace app\common\business;


use Godruoyi\Snowflake\Snowflake;
use think\facade\Cache;

class Order
{
    public $model = null;

    public function __construct() {
        //初始化模型对象
        $this->model = new \app\common\model\mysql\Order();
    }

    public function save($data) {
        //生成订单号
        $orderId = (new Snowflake())->id();
        // 获取购物车选中的数据，并验证库存信息 =》 redis
        $carObj = new Cart();
        $selectedGoods = $carObj->getSlectedList($data['user_id']);
        if(empty($selectedGoods)) {
            return false;
        }
        //订单总金额
        $totalPrice = $selectedGoods['totalPrice'];
        //勾选的商品
        $selectedList = $selectedGoods['list'];
        $newSelectedList = array_map(function ($v) use ($orderId) {
            $v['sku_id'] = $v['id'];
            unset($v['id']);
            $v['order_id'] = $orderId;
            return $v;
        }, $selectedList);
        //订单数据组合
        $orderData = [
            'order_id' => $orderId,
            'total_price' => $totalPrice
        ];
        $orderData = array_merge($orderData, $data);
        //插入数据库  开启事务
        $this->model->startTrans();
        try {
            //新增order
            $id = $this->add($orderData);
            if (!$id) {
                return false;
            }
            //新增orderGoods
            $orderGoodsResult = (new \app\common\model\mysql\OrderGoods())->saveAll($newSelectedList);
            $orderGoodsResult = $orderGoodsResult->toArray();
            //商品sku库存更新
            $skuRes = (new GoodsSku())->updateStock($orderGoodsResult);
            // 删除购物车里面的下单商品
            $cartRes = (new Cart())->deleteRedis($data['user_id'], array_column($orderGoodsResult, 'sku_id'));
            $this->model->commit();

            //放入延迟队列 判断未支付订单
            try {
                Cache::zAdd(config('redis.order_status_key'), time()+config('redis.order_expire'), $orderId);
            } catch (\Exception $e) {
                //订单延迟队列出错  （记录日志）
            }

            return ["id" => $orderId];
        }catch (\Exception $e) {
            $this->model->rollback();
            return false;
        }
    }

    /**
     * 添加订单数据
     * @param $data
     * @return int|mixed
     */
    public function add($data) {
        $data['status'] = 1;
        try {
            $this->model->save($data);
        }catch (\Exception $e) {
            // 记录日志哦，便于后续问题的排查工作
            return 0;
        }
        // // 返回主键ID
        return $this->model->id;
    }

    /**
     * 获取订单详情
     * @param $userId
     * @param $id
     * @return array|\think\Model|null
     */
    public function getDetail($userId, $id) {
        //获取订单信息
        $res = $this->model->getDetail($userId, $id);
        if (!$res) {
            return [];
        }
        $res = $res->toArray();
        //获取订单商品
        $goods = (new OrderGoods())->getGoodsById($id);
        //组合
        $res['goods'] = $goods;
        return $res;
    }

    /**
     * @param $orderId
     * @param $time
     * @return bool
     */
    public function checkOrderStatus() {

        $result = Cache::store('redis')->zRangeByScore("order_status", 0, time(), ['limit' => [0, 1]]);

        if (empty($result) || empty($result[0])) {
            return false;
        }

        try {
            //删除
            $delRedis = Cache::store('redis')->zRem("order_status", $result[0]);
        } catch (\Exception $e) {
            // 记录日志
            $delRedis = "";
        }
        if ($delRedis) {
            $orderId = $result[0];
            echo "订单id:{$orderId}在规定时间内没有完成支付 我们判定为无效订单删除" . PHP_EOL;
            $this->model->startTrans();
            try {
                /**
                 * 第一步： 根据订单ID 去数据库order表里面获取当前这条订单数据 看下当前状态是否是待支付:status = 1
                 *        如果是那么我们需要把状态更新为 已取消 status = 7， 否则不需要care
                 */

                $res = $this->model->where('order_id', $orderId)->find()->toArray();
                if ($res['status'] != 1) {
                    return true;
                }
                //设置无效订单
                $this->model->where('order_id', $orderId)->save(['status'=> 7]);
                /** 第二步： 如果第一步status修改7之后， 我们需要再查询order_goods表， 拿到 sku_id num  把sku表数据库存增加num
                 *        goods表总库存也需要修改。
                 */
                $goods = (new OrderGoods())->getGoodsById($orderId);
                $skuRes = (new GoodsSku())->addStock($goods);
                $this->model->commit();
            } catch (\Exception $e) {
                $this->model->rollback();
            }

        } else {
            return false;
        }

        return true;
    }

    public function getList($pageSize, $pageNum) {
        $order = [
            'create_time' => 'desc'
        ];
        try {
            $data = $this->model->order($order)->paginate([
                'page'  => $pageNum, //当前页
                'list_rows' => $pageSize, //每页数量
            ]);
            if (!$data) {
                return [];
            }
            $data = $data->toArray();
            //获取商品
            foreach ($data['data'] as $k=>$v) {
                //设置支付状态
                $statusDesc = "未支付";
                switch ($v['status']) {
                    case 1:
                        $statusDesc = "未支付";
                        break;
                    case 2:
                        $statusDesc = "已付款";
                        break;
                    case 3:
                        $statusDesc = "已发货";
                        break;
                    case 4:
                        $statusDesc = "已收货";
                        break;
                    case 5:
                        $statusDesc = "已完成";
                        break;
                    case 6:
                        $statusDesc = "退款退货";
                        break;
                    case 7:
                        $statusDesc = "已取消";
                        break;
                }
                $orderId = $v['order_id'];
                $goods = (new \app\common\model\mysql\OrderGoods())->where('order_id', $orderId)->select();
                if ($goods) {
                    $goods = $goods->toArray();
                } else {
                    $goods = [];
                }
                $data['data'][$k]['statusDesc'] = $statusDesc;
                $data['data'][$k]['goods'] = $goods;
            }
        } catch (\Exception $e) {
            return [];
        }
        return $data;
    }
}